package com.ecoolex.hotel.saas.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.BigDecimalUtil;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.RandomUtil;
import com.ecoolex.hotel.saas.core.dao.SalesUserWalletWithdrawalApplyDAO;
import com.ecoolex.hotel.saas.core.service.WeChatPayService;
import com.ecoolex.hotel.saas.entity.SalesUserWallet;
import com.ecoolex.hotel.saas.entity.SalesUserWalletWithdrawalApply;
import com.ecoolex.hotel.saas.entity.SalesUserWalletWithdrawalApply.Column;
import com.ecoolex.hotel.saas.entity.SalesUserWalletWithdrawalApplyExample;
import com.ecoolex.hotel.saas.entity.StoreWeixinConfig;
import com.ecoolex.hotel.saas.entity.SalesUserWalletWithdrawalApplyExample.Criteria;
import com.ecoolex.hotel.saas.enums.SalesUserWalletWithdrawalApplyStatus;
import com.ecoolex.hotel.saas.pojo.QuerySalesUserWalletWithdrawalApplyDTO;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.NumberUtils;

@Service
public class SalesUserWalletWithdrawalApplyManager {
	
    @Autowired
    private SalesUserWalletWithdrawalApplyDAO dao;
    
    @Autowired
    private SalesUserWalletManager salesUserWalletManager;
    
    @Autowired
    private WeChatPayService weChatPayService;
    
    @Autowired
	private StoreWeixinConfigManager storeWeixinConfigManager;
    
    public SalesUserWalletWithdrawalApply getSalesUserWalletWithdrawalApply(Integer applyId) {
		return dao.selectByPrimaryKeyWithLogicalDelete(applyId, SalesUserWalletWithdrawalApply.NOT_DELETED);
	}

	public Pagination<SalesUserWalletWithdrawalApply> queryForUser(Integer storeId, Integer userId, Page page) {
		return Pagination.create(page, 
			dao.countForUser(storeId, userId),
			() -> dao.queryForUser(storeId, userId, page));
	}
	
	
	public Pagination<SalesUserWalletWithdrawalApply> query(QuerySalesUserWalletWithdrawalApplyDTO query, Page page) {
		return Pagination.create(page, 
			dao.count(query),
			() -> dao.query(query, page));
	}

	/**
	 * 后台同意提现申请
	 * @param apply
	 * @param updateUser
	 * @return
	 */
	@Transactional
	public SalesUserWalletWithdrawalApply agree(SalesUserWalletWithdrawalApply apply, String updateUser){
		apply.setStatus(SalesUserWalletWithdrawalApplyStatus.AGREE.real());
		apply.setUpdateUser(updateUser);
		apply.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(apply, Column.status,Column.remark,Column.updateUser,Column.updateTime);
		SalesUserWallet salesUserWallet = salesUserWalletManager.get(apply.getWalletId());
		//钱包冻结资金扣除
		salesUserWalletManager.reduceFrozenAmt(salesUserWallet, apply.getApplyId(), apply.getApplyAmt(), updateUser);
		StoreWeixinConfig weixinConfig = storeWeixinConfigManager.getStoreWeixinConfig(salesUserWallet.getStoreId());
		if(Check.notNull(weixinConfig) && weixinConfig.getCanOnlineEntPay()) {
			//发起微信付款给用户
			weChatPayService.entPay(weixinConfig, salesUserWallet.getUserId(), apply.getApplyNo(), apply.getApplyAmt(), "提现");
		}
		return apply;
	}

	/**
	 * 后台拒绝提现申请
	 * @param apply
	 * @param updateUser
	 * @return
	 */
	public SalesUserWalletWithdrawalApply refuse(SalesUserWalletWithdrawalApply apply, String updateUser){
		apply.setStatus(SalesUserWalletWithdrawalApplyStatus.REFUSE.real());
		apply.setUpdateUser(updateUser);
		apply.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(apply, Column.status,Column.remark,Column.refuseReason,Column.updateUser,Column.updateTime);
		//钱包冻结资金转入余额
		salesUserWalletManager.frozenAmtToBalance(apply.getWalletId(), apply.getApplyAmt(), updateUser);
		return apply;
	}
    
    /**
     * 用户发起提现
     * @param walletId
     * @param applyAmt
     * @param createUser
     * @return
     */
    @Transactional
    public SalesUserWalletWithdrawalApply submitApply(Integer walletId, BigDecimal applyAmt, String createUser){
		BizAssert.isTrue(Check.isGreatThan(applyAmt,BigDecimal.ZERO), ResultCode.VERIFY.build(1), "请输入正确金额");
    	//检查余额是否足够
    	BizAssert.isTrue(salesUserWalletManager.checkBalance(walletId, applyAmt),ResultCode.BIZ.build(2), "提现金额大于钱包余额");
    	SalesUserWalletWithdrawalApply withdrawalApply = new SalesUserWalletWithdrawalApply();
    	withdrawalApply.setWalletId(walletId);
    	withdrawalApply.setApplyNo(createApplyNo());
    	withdrawalApply.setApplyAmt(applyAmt);
    	withdrawalApply.setStatus(SalesUserWalletWithdrawalApplyStatus.WAIT_AUDIT.real());
    	withdrawalApply.setDeleted(SalesUserWalletWithdrawalApply.NOT_DELETED);
    	withdrawalApply.setCreateUser(createUser);
    	withdrawalApply.setCreateTime(Date.from(Instant.now()));
    	withdrawalApply.setUpdateUser(createUser);
    	withdrawalApply.setUpdateTime(Date.from(Instant.now()));
    	dao.insert(withdrawalApply);
    	//冻结钱包余额
    	salesUserWalletManager.balanceToFrozen(walletId, applyAmt, createUser);
		return withdrawalApply;
	}

    private String createApplyNo() {
		String applyNo = RandomUtil.randomInt(18);
		SalesUserWalletWithdrawalApply apply = getByApplyNo(applyNo);
		if (Check.notNull(apply)) {
			applyNo = createApplyNo();
		}
		return applyNo;
	}
	
	public SalesUserWalletWithdrawalApply getByApplyNo(String applyNo) {
		SalesUserWalletWithdrawalApplyExample example = new SalesUserWalletWithdrawalApplyExample();
		Criteria criteria = example.createCriteria();
		criteria.andApplyNoEqualTo(applyNo);
		return dao.selectOneByExample(example);
	}
}